/*
 * Copyright (C) 2017 yixun All Rights Reserved.
 * 
 * SubscribeTransServiceImpl.java
 */
package com.emm.yixun.basic.service.impl;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.emm.yixun.basic.mapper.SubscribeTransMapper;
import com.emm.yixun.basic.service.HaveReceiveRefundService;
import com.emm.yixun.basic.service.NeedReceiveRefundService;
import com.emm.yixun.basic.service.ProjectService;
import com.emm.yixun.basic.service.SignedService;
import com.emm.yixun.basic.service.SubscribeService;
import com.emm.yixun.basic.service.SubscribeTransService;
import com.emm.yixun.common.model.HaveReceiveRefund;
import com.emm.yixun.common.model.NeedReceiveRefund;
import com.emm.yixun.common.model.Project;
import com.emm.yixun.common.model.Signed;
import com.emm.yixun.common.model.Subscribe;
import com.emm.yixun.common.model.SubscribeTrans;
import com.emm.yixun.common.model.dto.HaveReceiveRefundDto;
import com.emm.yixun.common.model.dto.NeedReceiveRefundDto;
import com.emm.yixun.common.model.dto.SignedDto;
import com.emm.yixun.common.model.dto.SubscribeDto;
import com.emm.yixun.common.model.dto.SubscribeTransDto;
import com.emm.yixun.common.model.dto.SubscribeTransRequestDto;
import com.emm.yixun.common.model.enums.AuditStatusEnum;
import com.emm.yixun.common.model.enums.BusinessFlagEnum;
import com.emm.yixun.common.model.enums.BusinessStatusEnum;
import com.emm.yixun.common.model.enums.BusinessTypeEnum;
import com.emm.yixun.common.model.enums.ContactTypeEnum;
import com.emm.yixun.common.model.enums.DelFlagEnum;
import com.emm.yixun.common.model.enums.DocTypeEnum;
import com.emm.yixun.common.model.enums.HousingFundTypeEnum;
import com.emm.yixun.common.model.enums.NeedStatusEnum;
import com.emm.yixun.common.model.enums.PaymentMethodEnum;
import com.emm.yixun.common.model.enums.ReceivablesTypeEnum;
import com.emm.yixun.common.page.Page;
import com.emm.yixun.common.utils.BeanUtil;


/**
 * [文件名称]<br>
 * SubscribeTransServiceImpl.java<br>
 * <br>
 * [文件描述]<br>
 * 认购合同收款 service interface impl<br>
 * <br>
 * [修改记录]<br>
 * 2017-08-11 15:39:30 创建 陶俊代码生成器<br>
 * 
 * @author 陶俊代码生成器
 * @version 1.00
 */
@Service("subscribeTransService")
public class SubscribeTransServiceImpl implements SubscribeTransService {
	
	@Autowired
	private SubscribeTransMapper mapper;
	
	@Autowired
	private SubscribeService subscribeService;
	
	@Autowired
	private ProjectService projectService;
	
	@Autowired
	private SignedService signedService;
	
	@Autowired
	private NeedReceiveRefundService needReceiveRefundService;
	
	@Autowired
	private HaveReceiveRefundService haveReceiveRefundService;
	
	/**
	 * @param entity 搜索条件
	 * @param begin 分页开始行数[不包含]
	 * @param end 分页结束行数[包含]
	 * @return 分页记录
	 */
	@Transactional(readOnly = true)
	public Page<SubscribeTrans> getPageModel(SubscribeTransDto entity,int begin,int end){
		Integer total = mapper.count(entity);
		List<SubscribeTrans> rows = mapper.list(entity,begin,end);
	    Page<SubscribeTrans> msr = new Page<SubscribeTrans>(total, rows);
	    msr.setPageSize(end);
		return msr;
	}

	/**
	 * 查询列表
	 * @param entity 搜索条件
	 * @return 分页记录
	 */
	public List<SubscribeTrans> selectListByDto(SubscribeTransDto entity){
		return mapper.selectListByDto(entity);
	}
	
	/**
	 * 查询单个
	 * @param entity 搜索条件
	 * @return 分页记录
	 */
	public SubscribeTrans selectByDto(SubscribeTransDto entity){
		return mapper.selectByDto(entity);
	}
	
	/**
	 * @param entity 搜索条件
	 * @return 分页记录
	 */
	public SubscribeTrans selectById(Long id){
		if(id!=null){
			return mapper.selectById(id);
		}
		return null;
	}
	/**
	 * @param entity 新增记录的详细信息
	 * @return 新增行数
	 */
	public SubscribeTransDto create(SubscribeTransDto entity) {
		entity.setCreateTime(Calendar.getInstance().getTime());
		mapper.add(entity);
		return entity;
	}

	/**
	 * @param entity 更新记录的详细信息
	 * @return 更新行数
	 */
	public int update(SubscribeTransDto entity) {
		entity.setUpdateTime(Calendar.getInstance().getTime());
		return mapper.edit(entity);
	}
    
	/**
	 * @param entity 待删除的记录信息
	 * @return 删除行数
	 */
	public int destroy(SubscribeTransDto entity) {
		return mapper.del(entity);
	}
	
	/**
	 * @param entity 新增或更新
	 * @return 新增行数
	 */
	public int saveOrUpdate(SubscribeTransDto entity) {
		if(entity!=null&&entity.getId()!=null){
			return update(entity);
		}else{
			create(entity);
			return 1;
		}
	}

	public String subcribeTrans(SubscribeTransRequestDto requestDto) {
	   try {
	       Subscribe subscribe = subscribeService.selectById(requestDto.getSubId());
		Project project = projectService.selectById(subscribe.getProjectId()); 
		if(!StringUtils.isEmpty(project.getBindReceivables())&&project.getBindReceivables().equals("0")){ //已经开通绑定收款
		    if(subscribe.getTransId()==null){ //还有生成过签约记录
			SignedDto signedDto = new SignedDto();
			signedDto.setMerchantId(project.getMerchantId());
			signedDto.setCustomerId(subscribe.getCustomerId());
			signedDto.setProjectId(subscribe.getProjectId());
			signedDto.setProjectCode(project.getProjectCode());
			signedDto.setRoomId(subscribe.getRoomId());
			signedDto.setSubscribeId(subscribe.getId());
			signedDto.setContactType(ContactTypeEnum.NORMAL.getNo());
			signedDto.setDidTime(new Date());
			signedDto.setAuditStatus(AuditStatusEnum.SUCCESS.getNo());
			signedDto.setCalculateArea(subscribe.getCalculateArea());
			signedDto.setSignPrice(subscribe.getSubscribePrice());
			signedDto.setCheckDate(new Date());
			signedDto.setUserCode(subscribe.getUserCode());
			signedDto.setAccessCode(project.getAccessCode());
			signedDto.setCreateUserId(subscribe.getCreateUserId());
			signedDto.setCreateTime(new Date());
			signedDto.setDelFlag(DelFlagEnum.UNDEL.getNo());
			signedDto.setSignAmount(subscribe.getSubscribeAmount());
			signedDto.setBusinessStatus(BusinessStatusEnum.SIGNED.getNo());
			signedDto.setPaymentMethod(PaymentMethodEnum.LUMP_SUM.getNo());
			SignedDto createSigned = signedService.create(signedDto);
			
			//创建签约下面的待收款
			NeedReceiveRefundDto refundDto = createNeedReceiveRefund(createSigned.getId(), requestDto, subscribe);
			
			//把认购金额转到新签约下面 已收款
			createHaveReceive(refundDto.getId(),createSigned.getId(), requestDto, subscribe);
			
			
			//生成中间表信息
			SubscribeTransDto transDto = new SubscribeTransDto();
			transDto.setSubId(subscribe.getId());
			transDto.setRoomId(subscribe.getRoomId());
			transDto.setProjectId(subscribe.getProjectId());
			transDto.setSigId(createSigned.getId());
			transDto.setSubContractAmount(requestDto.getTransAmount());
			transDto.setMerchantId(subscribe.getMerchantId());
			transDto.setDelFlag(DelFlagEnum.UNDEL.getNo());
			SubscribeTransDto trans = create(transDto);
			
			//修改认购tranId 
			SubscribeDto subUpd = new SubscribeDto();
			subUpd.setTransId(trans.getId());
			subUpd.setId(subscribe.getId());
			subscribeService.update(subUpd);
		    }else{
			//修改中间表信息
			SubscribeTrans trans = mapper.selectById(subscribe.getTransId());
			SubscribeTransDto dto = new SubscribeTransDto();
			dto.setId(subscribe.getTransId());
			dto.setSubContractAmount(requestDto.getTransAmount().add(trans.getSubContractAmount()));
			dto.setDelFlag(DelFlagEnum.UNDEL.getNo());
			mapper.edit(dto);
			createNeedReceiveRefund(trans.getSigId(), requestDto, subscribe);
		    }
		}else{
		  return  "未开通认购合同收款!";
		}
           } catch (Exception e) {
               return "系统异常";
           }
	   return null;
	}
	
	public NeedReceiveRefundDto createNeedReceiveRefund(Long sigId,SubscribeTransRequestDto requestDto,Subscribe subscribe){
	    	NeedReceiveRefundDto needReceiveRe = new NeedReceiveRefundDto();
	    	needReceiveRe.setRelationId(sigId);
	    	needReceiveRe.setBusinessType(BusinessTypeEnum.SIGNED.getNo());
	    	needReceiveRe.setTotalReceivablesAmount(requestDto.getTransAmount());
		needReceiveRe.setCustomerId(subscribe.getCustomerId());
		needReceiveRe.setRoomId(subscribe.getRoomId());
		needReceiveRe.setHousingFundType(HousingFundTypeEnum.FUNDTYPE_25.getNo());
		needReceiveRe.setBusinessFlag(BusinessFlagEnum.BUSINESSFLAG_5.getNo());
		needReceiveRe.setStatus("1");
		needReceiveRe.setPostponedStatus("0");
		needReceiveRe.setDocType("0");
		needReceiveRe.setMerchantId(subscribe.getMerchantId());
		needReceiveRe.setAccessCode(subscribe.getAccessCode());
		needReceiveRe.setUserCode(subscribe.getUserCode());
		needReceiveRe.setCreateUserId(subscribe.getCreateUserId());
		needReceiveRe.setCreateTime(new Date());
		needReceiveRe.setUpdateTime(new Date());
		needReceiveRe.setReceivablesFunds("一次性付款");
		needReceiveRe.setPaymentMethod(PaymentMethodEnum.LUMP_SUM.getNo());
		needReceiveRe.setDelFlag(DelFlagEnum.UNDEL.getNo());
		NeedReceiveRefundDto needRefunDto = needReceiveRefundService.create(needReceiveRe);
		return needRefunDto;
	}
	public void createHaveReceive(Long refunId,Long sigId,SubscribeTransRequestDto requestDto,Subscribe subscribe){
	    	HaveReceiveRefundDto haveReceive = new HaveReceiveRefundDto();
		haveReceive.setReceivablesId(refunId);
		haveReceive.setRelationId(sigId);
		haveReceive.setDeductibleAmount(BigDecimal.ZERO);
		haveReceive.setRealAmount(subscribe.getDepositReceivable());
		haveReceive.setDocType("0");
		haveReceive.setStatementDate(new Date());
		haveReceive.setReceivablesType("2");
		haveReceive.setTransferStatus("0");
		haveReceive.setCustomerId(subscribe.getCustomerId());
		haveReceive.setRoomId(subscribe.getRoomId());
		haveReceive.setPaymentMethod(PaymentMethodEnum.LUMP_SUM.getNo());
		haveReceive.setHousingFundType(HousingFundTypeEnum.FUNDTYPE_5.getNo());
		haveReceive.setBusinessFlag(BusinessFlagEnum.BUSINESSFLAG_13.getNo());
		haveReceive.setMerchantId(subscribe.getMerchantId());
		haveReceive.setAccessCode(subscribe.getAccessCode());
		haveReceive.setUserCode(subscribe.getUserCode());
		haveReceive.setCreateUserId(subscribe.getCreateUserId());
		haveReceive.setCreateTime(new Date());
		haveReceive.setDelFlag(DelFlagEnum.UNDEL.getNo());
		haveReceive.setUpdateTime(new Date());
		haveReceiveRefundService.create(haveReceive);
	}

	public void signedTransfer(Long signedId) {
	    Signed signed = signedService.selectById(signedId);
	    if(signed!=null&&signed.getSubscribeId()!=null){ //认购转签约
		Subscribe subscribe = subscribeService.selectById(signed.getSubscribeId());
			if(subscribe!=null&&subscribe.getTransId()!=null){
			    SubscribeTrans trans = mapper.selectById(subscribe.getTransId());
			    if(trans!=null){
					//删除伪签约记录
					SignedDto signedDto = new SignedDto();
					signedDto.setId(trans.getSigId());
					signedService.destroy(signedDto);
					
					//删除伪签约的代收款
					NeedReceiveRefundDto queryNeedReceive = new NeedReceiveRefundDto();
					queryNeedReceive.setRelationId(trans.getSigId());
					queryNeedReceive.setBusinessType("2");
					queryNeedReceive.setStatus("1");
					List<NeedReceiveRefund> needReceiveList = needReceiveRefundService.selectListByDto(queryNeedReceive);
					for (NeedReceiveRefund need:needReceiveList) {
					    NeedReceiveRefundDto upd = new NeedReceiveRefundDto();
					    BeanUtil.convert2T(upd, need);
					    needReceiveRefundService.destroy(upd);
					}
			    }
			    NeedReceiveRefundDto needReceive = new NeedReceiveRefundDto();
			    needReceive.setRelationId(signedId);
			    needReceive.setBusinessType(BusinessTypeEnum.SIGNED.getNo());
			    needReceive.setDocType(DocTypeEnum.COLLECTION.getNo());
			    List<NeedReceiveRefund>  needReceiveList = needReceiveRefundService.selectListByDto(needReceive);
			    Map<Long, BigDecimal> needMap = new HashMap<Long, BigDecimal>();
			    if(needReceiveList!=null&&needReceiveList.size()>0){
			    	for(NeedReceiveRefund nrr: needReceiveList){
			    		needMap.put(nrr.getId(), nrr.getTotalReceivablesAmount());
			    	}
			    	HaveReceiveRefundDto queryRefund = new HaveReceiveRefundDto(); //查询伪签约的已收款
			    	queryRefund.setRelationId(trans.getSigId());
					 queryRefund.setReceivablesType("2");
					 queryRefund.setHousingFundType(HousingFundTypeEnum.FUNDTYPE_5.getNo());
					 List<HaveReceiveRefund> refundList = haveReceiveRefundService.selectListByDto(queryRefund);
					 for (HaveReceiveRefund ref:refundList) {
						 if(!ReceivablesTypeEnum.SUBSCRIBE.getNo().equals(ref.getReceivablesType())){
							 HaveReceiveRefundDto haveUpd = new HaveReceiveRefundDto();
						     BeanUtil.convert2T(haveUpd, ref);
						     haveUpd.setRelationId(signedId);
						     haveUpd.setReceivablesId(needReceiveList.get(0).getId());
						     haveUpd.setHousingFundType(HousingFundTypeEnum.FUNDTYPE_5.getNo());
						     haveUpd.setBusinessFlag(BusinessFlagEnum.BUSINESSFLAG_9.getNo());
						     haveUpd.setPaymentMethod(PaymentMethodEnum.LUMP_SUM.getNo());
						     haveUpd.setRemark("伪签约转账");
						     haveReceiveRefundService.update(haveUpd);
						 }
				 	}
			    }
			    
			    //新签约待收
			    for(Map.Entry<Long, BigDecimal> nrr: needMap.entrySet()){
			    	//签约代收款、签约已收款金额比较
				    HaveReceiveRefundDto hrrDto = new HaveReceiveRefundDto();
				    hrrDto.setRelationId(signedId);
				    hrrDto.setReceivablesId(nrr.getKey());
				    hrrDto.setDocType(DocTypeEnum.COLLECTION.getNo());
				    double haveReceiveAmount = haveReceiveRefundService.haveReceiveAmount(hrrDto)==null?0:haveReceiveRefundService.haveReceiveAmount(hrrDto);
				    if(nrr.getValue().compareTo(BigDecimal.valueOf(haveReceiveAmount)) == 0){
				    	NeedReceiveRefundDto nrrDto = new NeedReceiveRefundDto();
		    			nrrDto.setId(nrr.getKey());
		    			nrrDto.setStatus(NeedStatusEnum.YES.getNo());
		    			needReceiveRefundService.update(nrrDto);
				    }
			    }
			}
	    }
	}
	
}
